home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Black Crawling Systems Archive Release 1.0
/
Black Crawling Systems Archive Release 1.0 (L0pht Heavy Industries, Inc.)(1997).ISO
/
advisories
/
LC15SRC.ZIP
/
util.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-07-11
|
8KB
|
243 lines
#include "includes.h"
void str_to_key(unsigned char *str,unsigned char *key);
void usage(char *progname);
void fill_user_struct(int, char *dastring, struct user_struct *da_struct);
void LMword(char *passwd, char *word);
char *atob(char *hexstring,int size);
int htoi(char c);
int PutUniCode(char *dst,char *src);
int isvalid_userline(int, char *str);
/*
* Convert a 7 byte array into an 8 byte des key with odd parity.
*/
void str_to_key(unsigned char *str,unsigned char *key)
{
void des_set_odd_parity(des_cblock *);
int i;
key[0] = str[0]>>1;
key[1] = ((str[0]&0x01)<<6) | (str[1]>>2);
key[2] = ((str[1]&0x03)<<5) | (str[2]>>3);
key[3] = ((str[2]&0x07)<<4) | (str[3]>>4);
key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5);
key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6);
key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7);
key[7] = str[6]&0x7F;
for (i=0;i<8;i++) {
key[i] = (key[i]<<1);
}
des_set_odd_parity((des_cblock *)key);
}
void usage(char *progname){
char *p;
p = strrchr(progname, '\\');
if (p == NULL)
p = progname;
else
p++;
fprintf(stderr, "Usage: %s -p <pwfile> -w <wordlist> -o <ofile> -b"
" [-l || n]\n", p);
fprintf(stderr, " -p <pwfile> The password file to read from in pwdump format\n");
fprintf(stderr, " -P <pwfile> The password file to read from in sniffer format\n");
fprintf(stderr, " -w <wordlist> The dictionary of words to try\n");
fprintf(stderr, " -o <ofile> File to write results to - if not\n");
fprintf(stderr, " specified defaults to stdout\n");
fprintf(stderr, " -b Brute force through the entire keyspace\n");
fprintf(stderr, " <A-Z takes 26 hours on PPRO 200>\n");
fprintf(stderr, " -l Only go after the LANMAN password\n");
fprintf(stderr, " -n Only go after the NT Dialect password [dumb!]\n");
fprintf(stderr, " without the -l or -n it goes after both\n");
fprintf(stderr, " which is still much faster than going after\n");
fprintf(stderr, " the NT Dialect password only!\n");
fprintf(stderr, "\n");
fprintf(stderr, " Note: Both -p and -w are required, unless -b is"
" specified\n");
fprintf(stderr, " in which case -w must be ommited\n");
fprintf(stderr, " mudge@l0pht.com\n");
exit(1);
}
void fill_user_struct(int pwdump, char *dastring, struct user_struct *da_struct){
char *tmp, *atobstr;
/* clear out the sucker */
memset(da_struct, '\0', sizeof(struct user_struct));
da_struct->pwdumpval = pwdump;
if (pwdump){
strncpy(da_struct->username, strtok(dastring, ":"), 128);
strtok(NULL, ":"); /* skip over UID */
tmp = strtok(NULL, ":");
if (strncmp(tmp, "NO PASSWORD", 11) == 0){
strcpy(da_struct->lmhash, "DISABLED?");
strcpy(da_struct->nthash, "DISABLED?");
} else if (strncmp(tmp, "********", 8) == 0){
strcpy(da_struct->lmhash, "NULL PASSWD?");
strcpy(da_struct->nthash, "NULL PASSWD?");
} else {
strncpy(da_struct->lmhash, tmp, 32);
strncpy(da_struct->nthash, strtok(NULL, ":"), 32);
}
if ((strncmp(da_struct->lmhash, "DISABLED?", 9) != 0) \
&& (strncmp(da_struct->lmhash, "NULL PASSWD?", 12) != 0 )){
atobstr = atob(da_struct->lmhash, 32);
memcpy(da_struct->lmhashb, atobstr, 16);
free(atobstr);
atobstr = atob(da_struct->nthash, 32);
memcpy(da_struct->nthashb, atobstr, 16);
free(atobstr);
}
/* if the second part of the lanman key is 0xAAD3B435B51404EE then
the password is 7 chars or less and we don't need to spin the
extra CPU cycles */
if (memcmp(&(da_struct->lmhash[16]), "AAD3B435B51404EE", 16) == 0)
da_struct->under7 = 1;
else
da_struct->under7 = 0;
} else { /* we are reading from a sniffer file */
strncpy(da_struct->username, strtok(dastring, ":"), 128);
tmp = strtok(NULL, ":"); /* get the password length */
if (atoi(tmp) >= 7)
da_struct->under7 = 0;
else
da_struct->under7 = 1;
tmp = strtok(NULL, ":"); /* get the 8byte challenge - note that we
have it stored in ascii so it is 16 bytes
to begin with */
atobstr = atob(tmp, 16);
memcpy(da_struct->server_chall, atobstr, 8);
free(atobstr);
tmp = strtok(NULL, ":");
atobstr = atob(tmp, 48);
memcpy(da_struct->lmresp_b, atobstr, 24);
free(atobstr);
tmp = strtok(NULL, ":");
atobstr = atob(tmp, 48);
memcpy(da_struct->ntresp_b, atobstr, 24);
free(atobstr);
}
da_struct->lmdone = 0;
da_struct->ntdone = 0;
da_struct->already_printed = 0;
da_struct->next = NULL;
da_struct->previous = NULL;
}
void LMword(char *passwd, char *word){
size_t i;
int word_len;
word_len = strlen(word);
for (i=0; i < word_len; i++)
word[i] = toupper(word[i]);
if (word_len < 14){
memcpy(passwd, word, strlen(word));
for (i=0; i<= (strlen(passwd)); i++){
if ((passwd[i] == '\r') || (passwd[i] == '\n'))
passwd[i] = '\0';
}
}
else
memcpy(passwd, word, 14);
}
/* the routines atob() and htoi() were lifted from code by
Josh Daymont - with only minor modifications */
char *atob(char *hexstring,int size) {
int i, value;
unsigned char c;
char *str1, *str2;
value = (size/2)+1;
str1 = (char *)(malloc((unsigned)value));
str2 = str1; /* save pointer to beginning */
for (i=0; i<size-1; i+=2){
if((value = htoi(*hexstring++)) == -1)
return(0);
c = value << 4;
if((value = htoi(*hexstring++)) == -1)
return(0);
c |= value;
*str1++ = (char)c;
}
return(str2);
}
int htoi(char c)
{
if (c == 32) return(0);
if('0' <= c && c <= '9')
return c - '0';
if('a' <= c && c <= 'f')
return 10 + c - 'a';
if('A' <= c && c <= 'F')
return 10 + c - 'A';
return -1;
}
/*******************************************************************
write a string in unicoode format
********************************************************************/
int PutUniCode(char *dst,char *src)
{
int ret = 0;
while (*src) {
dst[ret++] = src[0];
dst[ret++] = 0;
src++;
}
dst[ret++]=0;
dst[ret++]=0;
return(ret-2); /* the way they do the md4 hash they don't represent
the last null. ie 'A' becomes just 0x41 0x00 - not
0x41 0x00 0x00 0x00 */
}
/* quick scan of line read from password file and a return of 1 if it's
superficially valid, 0 otherwise - This should really be flushed out
and made more intelligent */
int isvalid_userline(int pwdump, char *str){
unsigned int i, counter;
counter = 0;
for (i=0; i < strlen(str); i++){
if (str[i] == ':')
counter++;
}
#ifdef _DEBUG
if (pwdump)
fprintf(stderr, "file is a pwdump file and line has %d delimiters\n", \
counter);
else
fprintf(stderr, "file is a sniffer file and line has %d delimiters\n", \
counter);
#endif
if ((pwdump && (counter == 6)) || (!(pwdump) && (counter == 4)))
return(1);
else
return(0);
}